#include "led.h"

#define MODE_INPUT                        0
#define MODE_OUTPUT_SPEED_10MHZ           1
#define MODE_OUTPUT_SPEED_2MHZ            2
#define MODE_OUTPUT_SPEED_50MHZ           3

#define CONF_OUTPUT_GENERAL_PUSH_PULL     0
#define CONF_OUTPUT_GENERAL_OPEN_DRAIN    1
#define CONF_OUTPUT_ALTERNATE_PUSH_PULL   2
#define CONF_OUTPUT_ALTERNATE_OPEN_DRAIN  3

#define CONF_INPUT_ANALOG                 0
#define CONF_INPUT_FLOATING               1
#define CONF_INPUT_PULL_UP_DOWN           2
#define CONF_INPUT_RESERVED               3

void LED_Init(void)
{
    // 1. GPIOA模块的时钟配置: RCC_APB2ENR 寄存器
    RCC->APB2ENR |= RCC_APB2ENR_IOPAEN;

    // 2. GPIO PA0的工作模式配置：输出模式，推挽输出: GPIOA_CRL 寄存器
    GPIOA->CRL &= ~(0xF << (0 * 4));
    GPIOA->CRL |= MODE_OUTPUT_SPEED_50MHZ       << (0 * 4);
    GPIOA->CRL |= CONF_OUTPUT_GENERAL_PUSH_PULL << (0 * 4 + 2);

    // 2. GPIO PA1的工作模式配置：输出模式，推挽输出: GPIOA_CRL 寄存器
    GPIOA->CRL &= ~(0xF << (1 * 4));
    GPIOA->CRL |= MODE_OUTPUT_SPEED_50MHZ       << (1 * 4);
    GPIOA->CRL |= CONF_OUTPUT_GENERAL_PUSH_PULL << (1 * 4 + 2);

    // 2. GPIO PA8的工作模式配置：输出模式，推挽输出: GPIOA_CRH 寄存器
    GPIOA->CRH &= ~(0xF << (0 * 4));
    GPIOA->CRH |= MODE_OUTPUT_SPEED_50MHZ       << (0 * 4);
    GPIOA->CRH |= CONF_OUTPUT_GENERAL_PUSH_PULL << (0 * 4 + 2);

    // 3. PA0输出高电平, 熄灭LED: GPIOA_ODR 寄存器
    LED_Off(LED1);
    // 3. PA1输出高电平, 熄灭LED: GPIOA_ODR 寄存器
    LED_Off(LED2);
    // 3. PA8输出高电平, 熄灭LED: GPIOA_ODR 寄存器
    LED_Off(LED3);
}

void LED_On(uint16_t led)
{
    GPIOA->ODR &= ~led;
}

void LED_Off(uint16_t led)
{
    GPIOA->ODR |= led;
}

void LED_Toggle(uint16_t led)
{
    // 需要先判断当前LED状态，读取IDR对应位
    if((GPIOA->IDR & led) == 0)
    {
        LED_Off(led);
    }
    else
    {
        LED_On(led);
    }
}
